#include <stdlib.h>

#include <windows.h>

#include "lib.h"
#include "libglob.h"
#include "screen.h"
#include "frame.h"
#include "bitmap.h"


pCScreen	
newCScreen(HWND hWnd, int32 Wid, int32 Hei, int32 Depth, char* ModeSwitchMsg, uint8 ucBitsPerPixel)
{
	HDC hdc;
	int bpp;
	pCScreen screen;


	// Get the current screen depth and set our Bmp code to 15 or 16 bit (RGB555 or RGB565)
	hdc = GetDC (hWnd);
		bpp = GetDeviceCaps(hdc, BITSPIXEL);
	ReleaseDC (hWnd, hdc);
	setImageFormat ((bool8)(bpp==15?1:0));

    // kharmon.  05-08-06.  Improved Graphics.  Set the mode to 24 bit color.
    setBitsPerPixel(ucBitsPerPixel);

	// Set the app default transparent color
	setTransparentColor (0, 255, 0);

	screen = (pCScreen)malloc(sizeof(CScreen));

	NOTUSED4(Wid, Hei, Depth, ModeSwitchMsg);

	if (screen && !CScreenConstruct(screen, hWnd))
	{
		free(screen);
		screen = 0;
	}
	screen->cBitDepth = bpp;
	gScreen = screen;
	return screen;
}

void		
deleteCScreen(pCScreen This)
{
	if (This)
	{
		CScreenDestruct(This);
		free(This);
	}
	gScreen = (pCScreen)0;
}

bool8	
CScreenConstruct(pCScreen This, HWND hWnd)
{
	This->chWnd = hWnd;

//	CScreenClearSystemPalette(This);

//	This->cLogPal.Version = 0x300;
//	This->cLogPal.NumberOfEntries= 256;
//	memset(This->cLogPal.aEntries, 0, 256 * sizeof(PALETTEENTRY));

	This->chPal = (HPALETTE)0;

	This->cFrame = (pCFrame)0;
	CScreenSizeChanged(This);

	return true;
}

void	
CScreenDestruct(pCScreen This)
{
	deleteCFrame(This->cFrame);
	This->cFrame = (pCFrame)0;

	if (This->chPal)
	{
		DeleteObject(This->chPal);
		This->chPal = (HPALETTE)0;
	}
}

void	
CScreenSizeChanged(pCScreen This)
{
	deleteCFrame(This->cFrame);
	This->cFrame = newCFrame(This->chWnd);

	if (This->cFrame)
	{

//		RGBQUAD quad[256];
//		int32 i;

		This->cSize.x = CFrameWidth(This->cFrame);
		This->cSize.y = CFrameHeight(This->cFrame);
/*
		for (i = 0; i < 256; i++)
		{
			quad[i].rgbRed		= This->cLogPal.aEntries[i].peRed;  
			quad[i].rgbGreen	= This->cLogPal.aEntries[i].peGreen;
			quad[i].rgbBlue		= This->cLogPal.aEntries[i].peBlue;
			quad[i].rgbReserved	= 0;
		}
*/
//		SetDIBColorTable(CFrameDC(This->cFrame), 0, 256, quad);

	}
	else
		This->cSize.x = This->cSize.y = 0;
}

void	
CScreenSetQuadPalette(pCScreen This, RGBQuad *pQuad, uint32 nEntries)
{

//	if (This->chPal)
//		DeleteObject(This->chPal);

//	This->chPal = CScreenCreateIdentityPalette(This,
//		(RGBQUAD *)pQuad, (int)nEntries);

//	CBitmapNewPalette((LOGPALETTE *)&This->cLogPal);
/*
	if (This->cFrame && CFrameDC(This->cFrame))
	{
		RGBQUAD quad[256];
		int32 i;

		for (i = 0; i < 256; i++)
		{
			quad[i].rgbRed		= This->cLogPal.aEntries[i].peRed;  
			quad[i].rgbGreen	= This->cLogPal.aEntries[i].peGreen;
			quad[i].rgbBlue		= This->cLogPal.aEntries[i].peBlue;
			quad[i].rgbReserved	= 0;
		}
//		SetDIBColorTable(CFrameDC(This->cFrame), 0, 256, quad);
	}
*/
}

void	
CScreenSetPalette(pCScreen This, char *Palette)
{
//	RGBQuad	quad[256];
//	int32		i;

//	if (!Palette)
//		return;
/*
	for (i = 0; i < 256; i++)
	{
		quad[i].red   = *Palette++;
		quad[i].green = *Palette++;
		quad[i].blue  = *Palette++;
		quad[i].reserved = 0;
	}
*/
//	CScreenSetQuadPalette(This, quad, 256);

}

void	
CScreenClear(pCScreen This)
{
}

void	
CScreenClearRect(pCScreen This, int32 Left, int32 Top, 
	int32 Right, int32 Bottom)
{
}

void	
CScreenBitmapBlt(pCScreen This, int32 DestX, int32 DestY, pCBitmap Src)
{
}

void	
CScreenTransparentBitmapBlt(pCScreen This, int32 DestX, int32 DestY,
	pCBitmap Src)
{
}

void	
CScreenBitmapBltSection(pCScreen This, int32 dx, int32 dy,
	int32 sx, int32 sy, int32 sw, int32 sh, pCBitmap Src)
{
}

void	
CScreenTransparentBitmapBltSection(pCScreen This, int32 dx, int32 dy,
	int32 sx, int32 sy, int32 sw, int32 sh, pCBitmap Src)
{
}

void	
CScreenFrameBlt(pCScreen This, int32 DestX, int32 DestY, pCFrame Src)
{
}

void	
CScreenFlipPages(pCScreen This)
{
	HDC hdc = GetDC(This->chWnd);

#if 0
	if (This->chPal)
		SelectPalette(hdc, This->chPal, FALSE);

	RealizePalette(hdc);

	GdiFlush();
	StretchBlt(hdc, 0, 0, This->cSize.x, This->cSize.y,
		CFrameDC(This->cFrame),
		0, 0, CFrameWidth(This->cFrame), CFrameHeight(This->cFrame),
		SRCCOPY);
#else
	CScreenFlipPagesDC(This, hdc);
#endif

	ReleaseDC(This->chWnd, hdc);
}

void
CScreenFlipPagesDC(pCScreen This, HDC hdc)
{
//	if (This->chPal)
//		SelectPalette(hdc, This->chPal, FALSE);

//	RealizePalette(hdc);

	GdiFlush();
	StretchBlt(hdc, 0, 0, This->cSize.x, This->cSize.y,
		CFrameDC(This->cFrame),
		0, 0, CFrameWidth(This->cFrame), CFrameHeight(This->cFrame),
		SRCCOPY);
}

/*
static void
CScreenClearSystemPalette(pCScreen This)
{
	ScreenPal Palette = { 0x300, 256 };
	HPALETTE ScreenPalette = 0;
	HDC ScreenDC;
	int Counter;
	UINT nMapped = 0;
	BOOL bOK = FALSE;
	int  nOK = 0;
  
	//*** Reset everything in the system palette to black
	for (Counter = 0; Counter < 256; Counter++)
	{
		Palette.aEntries[Counter].peRed = 0;
		Palette.aEntries[Counter].peGreen = 0;
		Palette.aEntries[Counter].peBlue = 0;
		Palette.aEntries[Counter].peFlags = PC_NOCOLLAPSE;
	}

	//*** Create, select, realize, deselect, and delete the palette
	ScreenDC = GetDC(NULL);
	ScreenPalette = CreatePalette((LOGPALETTE *)&Palette);

	if (ScreenPalette)
	{
		ScreenPalette = SelectPalette(ScreenDC,ScreenPalette,FALSE);
		nMapped = RealizePalette(ScreenDC);
		ScreenPalette = SelectPalette(ScreenDC,ScreenPalette,FALSE);
		bOK = DeleteObject(ScreenPalette);
	}

	nOK = ReleaseDC(NULL, ScreenDC);
}
*/
/*
static HPALETTE
CScreenCreateIdentityPalette(pCScreen This, RGBQUAD aRGB[], int nColors)
{
	int i;

	//*** Just use the screen DC where we need it
	HDC hdc = GetDC(NULL);

	//*** For SYSPAL_NOSTATIC, just copy the color table into
	//*** a PALETTEENTRY array and replace the first and last entries
	//*** with black and white
	if (GetSystemPaletteUse(hdc) == SYSPAL_NOSTATIC)
	{
		//*** Fill in the palette with the given values, marking each
		//*** as PC_NOCOLLAPSE
		for(i = 0; i < nColors; i++)
		{
			This->cLogPal.aEntries[i].peRed = aRGB[i].rgbRed;
			This->cLogPal.aEntries[i].peGreen = aRGB[i].rgbGreen;
			This->cLogPal.aEntries[i].peBlue = aRGB[i].rgbBlue;
			This->cLogPal.aEntries[i].peFlags = PC_NOCOLLAPSE;
		}

		//*** Mark any unused entries PC_NOCOLLAPSE
		for (; i < 256; ++i)
		{
			This->cLogPal.aEntries[i].peFlags = PC_NOCOLLAPSE;
		}

		//*** Make sure the last entry is white
		//*** This may replace an entry in the array!
		This->cLogPal.aEntries[255].peRed = 255;
		This->cLogPal.aEntries[255].peGreen = 255;
		This->cLogPal.aEntries[255].peBlue = 255;
		This->cLogPal.aEntries[255].peFlags = 0;

		//*** And the first is black
		//*** This may replace an entry in the array!
		This->cLogPal.aEntries[0].peRed = 0;
		This->cLogPal.aEntries[0].peGreen = 0;
		This->cLogPal.aEntries[0].peBlue = 0;
		This->cLogPal.aEntries[0].peFlags = 0;

	}
	else
	//*** For SYSPAL_STATIC, get the twenty static colors into
	//*** the array, then fill in the empty spaces with the
	//*** given color table
	{
		int nStaticColors;
		int nUsableColors;

		//*** Get the static colors from the system palette
		nStaticColors = GetDeviceCaps(hdc, NUMCOLORS);
		GetSystemPaletteEntries(hdc, 0, 256, This->cLogPal.aEntries);

		//*** Set the peFlags of the lower static colors to zero
		nStaticColors = nStaticColors / 2;

		for (i=0; i<nStaticColors; i++)
			This->cLogPal.aEntries[i].peFlags = 0;

		//*** Fill in the entries from the given color table
		nUsableColors = nColors - nStaticColors;
		for (; i<nUsableColors; i++)
		{
			This->cLogPal.aEntries[i].peRed = aRGB[i].rgbRed;
			This->cLogPal.aEntries[i].peGreen = aRGB[i].rgbGreen;
			This->cLogPal.aEntries[i].peBlue = aRGB[i].rgbBlue;
			This->cLogPal.aEntries[i].peFlags = PC_NOCOLLAPSE;
		}

		//*** Mark any empty entries as PC_NOCOLLAPSE

		for (; i<256 - nStaticColors; i++)
			This->cLogPal.aEntries[i].peFlags = PC_NOCOLLAPSE;

		//*** Set the peFlags of the upper static colors to zero
		for (i = 256 - nStaticColors; i<256; i++)
			This->cLogPal.aEntries[i].peFlags = 0;
	}

	//*** Remember to release the DC!
	ReleaseDC(NULL, hdc);

	//*** Return the palette
	return (HPALETTE)CreatePalette((LOGPALETTE *)&This->cLogPal);
}
*/